import Phaser from 'phaser';

class MainScene extends Phaser.Scene {
  constructor() {
    super({ key: 'MainScene' });
    this.player = null; // Initialize player property
    this.cursors = null; // Initialize cursors property
    this.bullets = null; // Initialize bullets group
    this.enemies = null; // Initialize enemies group
    this.enemyBullets = null; // Initialize enemy bullets group
    this.spaceKey = null; // Initialize space key listener
    this.lastFired = 0; // Track last fire time
    this.score = 0;
    this.playerLevel = 1; // Reset level
    this.levelUpScore = 50; // Reset level up score threshold // Initialize score
    this.lives = 3; // Initialize lives
    this.scoreText = null; // Initialize score text object
    this.livesText = null; // Initialize lives text object
    this.gameOverText = null; // Initialize game over text object
    this.restartText = null; // Initialize restart text object
    this.isGameOver = false; // Game over flag
    this.playerLevel = 1; // Initialize player level
    this.levelUpScore = 50; // Score needed for next level
    this.enemyTimer = null; // Timer for enemy spawning
    this.enemyFireTimer = null; // Timer for enemy firing
    this.levelText = null; // Initialize level text object
    this.starfield = null; // Initialize starfield background
  }

  preload() {
    // Load assets like images, sounds, etc.
    this.load.image('player', 'assets/player.svg'); // Load player image (updated to SVG)
    this.load.image('bullet', 'assets/bullet.svg'); // Load bullet image
    this.load.image('enemy', 'assets/enemy.svg'); // Load enemy image (assuming it exists)
    this.load.image('enemy_bullet', 'assets/bullet.svg'); // Load enemy bullet image (reusing player bullet for now)
    this.load.image('starfield', 'assets/new_background.jpg'); // Load new background image
  }

  create() {
    // Add starfield background
    this.starfield = this.add.tileSprite(0, 0, this.cameras.main.width, this.cameras.main.height, 'starfield');
    this.starfield.setOrigin(0, 0);
    this.starfield.setScrollFactor(0); // Keep background fixed relative to the camera

    // Add player sprite
    this.player = this.physics.add.sprite(this.cameras.main.width / 2, this.cameras.main.height - 100, 'player');
    this.player.setCollideWorldBounds(true); // Keep player within game bounds

    // Setup input handling
    this.cursors = this.input.keyboard.createCursorKeys(); // Enable keyboard input
    this.spaceKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE); // Add space key listener

    // Create bullets group
    this.bullets = this.physics.add.group({
      defaultKey: 'bullet',
      maxSize: 10 // Limit the number of bullets on screen
    });

    // Create enemies group
    this.enemies = this.physics.add.group({
        defaultKey: 'enemy',
        maxSize: 20 // Limit the number of enemies on screen
    });

    // Create enemy bullets group
    this.enemyBullets = this.physics.add.group({
        defaultKey: 'enemy_bullet',
        maxSize: 30 // Limit the number of enemy bullets
    });

    // Display Score
    this.scoreText = this.add.text(16, 16, 'Score: 0', { fontSize: '32px', fill: '#FFF' });

    // Display Lives
    this.livesText = this.add.text(this.cameras.main.width - 150, 16, 'Lives: 3', { fontSize: '32px', fill: '#FFF' });

    // Display Level
    this.levelText = this.add.text(16, 50, 'Level: 1', { fontSize: '32px', fill: '#FFF' }); // Add level display

    // Game Over Text (initially hidden)
    this.gameOverText = this.add.text(this.cameras.main.width / 2, this.cameras.main.height / 2 - 40, 'Game Over', { fontSize: '64px', fill: '#F00' });
    this.gameOverText.setOrigin(0.5);
    this.gameOverText.setVisible(false);

    // Restart Text (initially hidden)
    this.restartText = this.add.text(this.cameras.main.width / 2, this.cameras.main.height / 2 + 40, 'Click to Restart', { fontSize: '32px', fill: '#FFF' });
    this.restartText.setOrigin(0.5);
    this.restartText.setVisible(false);

    // Setup collision detection
    this.physics.add.overlap(this.bullets, this.enemies, this.hitEnemy, null, this);
    this.physics.add.overlap(this.player, this.enemies, this.hitPlayer, null, this);
    this.physics.add.overlap(this.player, this.enemyBullets, this.hitPlayerByEnemyBullet, null, this); // Collision for player and enemy bullets

    // Timer to spawn enemies
    this.enemyTimer = this.time.addEvent({
        delay: 1500, // Initial spawn delay
        callback: this.spawnEnemy,
        callbackScope: this,
        loop: true
    });

    // Timer for enemies to fire
    this.enemyFireTimer = this.time.addEvent({
        delay: 1500, // Enemies fire every 1500ms
        callback: this.enemyFire,
        callbackScope: this,
        loop: true
    });
  }

  update(time, delta) { // Add time and delta parameters
    if (this.isGameOver) {
        // Game over logic is handled by the pointerdown listener set in gameOver
        return; // Stop updates if game is over
    }

    // Scroll the background
    this.starfield.tilePositionY -= 0.5; // Adjust speed as needed

    // Reset velocity from previous frame
    this.player.setVelocity(0);

    if (this.cursors.left.isDown) {
      this.player.setVelocityX(-300); // Increased speed
    } else if (this.cursors.right.isDown) {
      this.player.setVelocityX(300); // Increased speed
    }

    if (this.cursors.up.isDown) {
      this.player.setVelocityY(-300); // Increased speed
    } else if (this.cursors.down.isDown) {
      this.player.setVelocityY(300); // Increased speed
    }

    // Fire bullet when space is pressed
    if (this.spaceKey.isDown && time > this.lastFired) {
      this.fireBullet(time);
    }

    // Update player bullets: remove if off-screen
    this.bullets.children.each(bullet => {
      if (bullet && bullet.active && bullet.y < 0) {
        bullet.setActive(false);
        bullet.setVisible(false);
        bullet.destroy(); // Properly remove from group
      }
    });

    // Update enemies: remove if off-screen
    this.enemies.children.each(enemy => {
        if (enemy && enemy.active && enemy.y > this.cameras.main.height) {
            enemy.setActive(false);
            enemy.setVisible(false);
            enemy.destroy(); // Properly remove from group
        }
    });

    // Update enemy bullets: remove if off-screen
    this.enemyBullets.children.each(bullet => {
        if (bullet && bullet.active && bullet.y > this.cameras.main.height) {
            bullet.setActive(false);
            bullet.setVisible(false);
            bullet.destroy(); // Properly remove from group
        }
    });
  }

  fireBullet(time) {
    const fireDelay = 150 - (this.playerLevel - 1) * 10; // Decrease delay slightly per level
    const bulletSpeed = -500 - (this.playerLevel - 1) * 20; // Increase speed slightly per level

    switch (this.playerLevel) {
      case 1:
        // Level 1: Single bullet
        this.createBullet(this.player.x, this.player.y - 30, 0, bulletSpeed);
        break;
      case 2:
        // Level 2: Two bullets slightly spread
        this.createBullet(this.player.x - 10, this.player.y - 30, 0, bulletSpeed);
        this.createBullet(this.player.x + 10, this.player.y - 30, 0, bulletSpeed);
        break;
      case 3:
         // Level 3: Three bullets (center and angled)
        this.createBullet(this.player.x, this.player.y - 30, 0, bulletSpeed);
        this.createBullet(this.player.x - 15, this.player.y - 20, -50, bulletSpeed);
        this.createBullet(this.player.x + 15, this.player.y - 20, 50, bulletSpeed);
        break;
      default:
        // Level 4+: Three bullets + faster center bullet
        this.createBullet(this.player.x, this.player.y - 30, 0, bulletSpeed * 1.2); // Faster center
        this.createBullet(this.player.x - 20, this.player.y - 20, -75, bulletSpeed);
        this.createBullet(this.player.x + 20, this.player.y - 20, 75, bulletSpeed);
        break;
    }

    this.lastFired = time + Math.max(50, fireDelay); // Ensure minimum delay
  }

  // Helper function to create a single bullet
  createBullet(x, y, velocityX, velocityY) {
    const bullet = this.bullets.get(x, y);
    if (bullet) {
      bullet.setActive(true);
      bullet.setVisible(true);
      bullet.body.velocity.x = velocityX;
      bullet.body.velocity.y = velocityY;
    }
  }

  // Original fireBullet logic (commented out or removed)
  /*
  fireBullet(time) {
    const bullet = this.bullets.get(this.player.x, this.player.y - 30); // Get a bullet from the group

    if (bullet) {
      bullet.setActive(true);
      bullet.setVisible(true);
      bullet.body.velocity.y = -500; // Increased bullet speed
      this.lastFired = time + 150; // Reduced firing delay
    }
  }
  */

  spawnEnemy() {
    const bullet = this.bullets.get(this.player.x, this.player.y - 30); // Get a bullet from the group

    if (bullet) {
      bullet.setActive(true);
      bullet.setVisible(true);
      bullet.body.velocity.y = -500; // Increased bullet speed
      this.lastFired = time + 150; // Reduced firing delay
    }
  }

  spawnEnemy() {
    const x = Phaser.Math.Between(50, this.cameras.main.width - 50); // Random x position within bounds
    const enemy = this.enemies.get(x, 0); // Get an enemy from the group at the top

    if (enemy) {
        enemy.setActive(true);
        enemy.setVisible(true);
        enemy.body.velocity.y = Phaser.Math.Between(100, 200); // Random downward speed
    }
  }

  enemyFire() {
    this.enemies.children.each(enemy => {
        if (enemy && enemy.active && Phaser.Math.Between(0, 5) === 0) { // Random chance to fire
            const bullet = this.enemyBullets.get(enemy.x, enemy.y + 30);
            if (bullet) {
                bullet.setActive(true);
                bullet.setVisible(true);
                bullet.body.velocity.y = 300; // Enemy bullet speed
            }
        }
    });
  }

  hitEnemy(bullet, enemy) {
    bullet.setActive(false);
    bullet.setVisible(false);
    bullet.destroy();
    enemy.setActive(false);
    enemy.setVisible(false);
    enemy.destroy();

    this.score += 10; // Increase score
    this.checkLevelUp(); // Check if player leveled up
    this.scoreText.setText('Score: ' + this.score);

    // Optional: Add explosion effect or sound here
  }

  checkLevelUp() {
    if (this.score >= this.levelUpScore) {
        this.playerLevel++;
        this.levelUpScore += 50 * this.playerLevel; // Increase score needed for next level
        this.levelText.setText('Level: ' + this.playerLevel);
        // Optional: Add level up effect/sound
        console.log(`Level Up! Reached Level ${this.playerLevel}. Next level at ${this.levelUpScore} score.`);

        // Adjust enemy spawn rate based on level
        const newDelay = Math.max(200, 1500 - (this.playerLevel - 1) * 100); // Decrease delay, minimum 200ms
        if (this.enemyTimer) {
            this.enemyTimer.remove(false);
        }
        this.enemyTimer = this.time.addEvent({
            delay: newDelay,
            callback: this.spawnEnemy,
            callbackScope: this,
            loop: true
        });
        console.log(`New enemy spawn delay: ${newDelay}ms`);
    }
  }

  hitPlayer(player, enemy) {
  }

  hitPlayer(player, enemy) {
    enemy.setActive(false);
    enemy.setVisible(false);
    enemy.destroy();

    this.loseLife();
  }

  hitPlayerByEnemyBullet(player, bullet) {
    bullet.setActive(false);
    bullet.setVisible(false);
    bullet.destroy();

    this.loseLife();
  }

  loseLife() {
    this.lives -= 1; // Decrease lives
    this.livesText.setText('Lives: ' + this.lives);

    // Optional: Add player hit effect or sound here
    this.player.setTint(0xff0000); // Flash red
    this.time.delayedCall(100, () => {
        if (!this.isGameOver) { // Only clear tint if not game over
             this.player.clearTint();
        }
    });

    if (this.lives <= 0) {
        this.gameOver();
    }
  }

  gameOver() {
    this.isGameOver = true;
    this.physics.pause(); // Pause physics
    this.player.setTint(0xff0000); // Indicate player is hit/dead
    this.enemyTimer.remove(false); // Stop spawning enemies
    this.enemyFireTimer.remove(false); // Stop enemies firing
    this.gameOverText.setVisible(true);
    this.gameOverText.setVisible(true);
    this.restartText.setVisible(true); // Show restart text

    // Add a one-time listener for pointer down anywhere to restart
    this.input.once('pointerdown', this.restartGame, this);
  }

  restartGame() {
    // Reset game state variables
    this.isGameOver = false;
    this.score = 0;
    this.playerLevel = 1; // Reset level
    this.levelUpScore = 50; // Reset level up score threshold
    this.lives = 3;

    // Update UI elements immediately (optional, as create will reset them too)
    // this.scoreText.setText('Score: ' + this.score);
    // this.livesText.setText('Lives: ' + this.lives);
    // this.gameOverText.setVisible(false);
    // this.restartText.setVisible(false);
    // this.levelText.setText('Level: ' + this.playerLevel); // Reset level text in create

    // Stop existing timers explicitly before restart (though gameOver already does this)
    if (this.enemyTimer) {
        this.enemyTimer.remove(false);
    }
    if (this.enemyFireTimer) {
        this.enemyFireTimer.remove(false);
    }

    // Clear player tint if it was set
    if (this.player) {
        this.player.clearTint();
    }

    this.scene.restart(); // Restart the current scene
  }
}

export default MainScene;